package com.atguigu.springbootrabbitmq.config;

import org.springframework.amqp.core.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类 发布确认高级
 *
 * 备份交换机
 *      有了mandatory参数和回退消息,我们获得了对无法投递消息的感知能力,有机会
 *      在生产者的消息无法被投递时发现并处理。但有时候,我们并不知道该如何处理这些无法
 *      路由的消息,最多打个日志,然后触发报警,再来手动处理。
 *      而通过日志来处理这些无法路由的消息是很不优雅的做法,特别是当生产者所在
 *      的服务有多台服务器的时候,手动复制日志会更加麻烦而且容易出错。
 *      而且设置mandatory参数会增加生产者的复杂性,需要添加处理这些被退回
 *      的消息的逻辑。
 *
 *
 *
 */
@Configuration
public class ConfirmConfig {

    //交换机
    public static final String CONFIRM_EXCHANGE_NAME = "confirm_exchange";

    //队列
    public static final String CONFIRM_QUEUE_NAME = "confirm_queue";

    //RoutingKey
    public static final String CONFIRM_ROUTING_KEY = "key1";

    //备份交换机
    public static final String BACKUP_EXCHANGE_NAME = "backup_exchange";

    //备份队列
    public static final String BACKUP_QUEUE_NAME = "backup_queue";

    //报警队列
    public static final String WARNING_QUEUE_NAME = "warning_queue";


    //交换机声明
    @Bean
    public DirectExchange confirmExchange() {
                //交换机的构建
                //关联备份交换机
        return ExchangeBuilder
                .directExchange(CONFIRM_EXCHANGE_NAME)
                .durable(true)
                //设置备份交换机
                .withArgument("alternate-exchange", BACKUP_EXCHANGE_NAME)
                .build();
    }

    //声明队列
    @Bean
    public Queue confirmQueue() {
        return QueueBuilder.durable(CONFIRM_QUEUE_NAME).build();
    }

    //绑定
    @Bean
    public Binding queueBindingExchange(@Qualifier("confirmQueue") Queue confirmQueue,
                                        @Qualifier("confirmExchange") DirectExchange directExchange)  {
        return BindingBuilder.bind(confirmQueue).to(directExchange).with(CONFIRM_ROUTING_KEY);
    }

    //备份交换机是扇出类型
    //扇出类型只要绑定就可以忽视RoutingKey
    @Bean
    public FanoutExchange backupExchange() {
        return new FanoutExchange(BACKUP_EXCHANGE_NAME);
    }

    //备份队列
    @Bean
    public Queue backupQueue() {
        return QueueBuilder.durable(BACKUP_QUEUE_NAME).build();
    }

    //报警队列
    @Bean
    public Queue warningQueue() {
        return QueueBuilder.durable(WARNING_QUEUE_NAME).build();
    }


    //绑定备份交换机和备份队列
    @Bean
    public Binding backupQueueBindingBackupExchange(@Qualifier("backupQueue") Queue backupQueue,
                                        @Qualifier("backupExchange") FanoutExchange backupExchange)  {
        return BindingBuilder.bind(backupQueue).to(backupExchange);
    }

    //绑定报警队列和备份交换机
    @Bean
    public Binding warningQueueBindingBackupExchange(@Qualifier("warningQueue") Queue warningQueue,
                                                    @Qualifier("backupExchange") FanoutExchange backupExchange)  {
        return BindingBuilder.bind(warningQueue).to(backupExchange);
    }





}